/*
 ------------------------------------------------------------------------------
 Copyright (C) 1996-2001 Id Software, Inc.

 This file is part of the Quake source code.

 The Quake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The Quake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the Quake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// msgSystem.h - message I/O functions
//


#ifndef __MSGSYSTEM_H__
#define __MSGSYSTEM_H__


/*
 ==============================================================================

 Message I/O:

 No memory is allocated, so the data buffer set with MSG_Init must be in static
 memory. If dynamically allocated memory is used, it should not be freed until
 all message I/O is completed.

 Byte ordering and alignment is handled automatically.

 It is safe to write to and read from a message buffer at the same time.

 ==============================================================================
*/

// Initializes a message buffer for writing and/or reading
void			MSG_Init (msg_t *msg, byte *data, int size, bool allowOverflow);

// Writing functions
int				MSG_GetWriteState (msg_t *msg);
void			MSG_SetWriteState (msg_t *msg, int bits);
void			MSG_ClearWriteState (msg_t *msg);

int				MSG_RemainingWriteBits (msg_t *msg);
int				MSG_RemainingWriteBytes (msg_t *msg);

void			MSG_WriteAlign (msg_t *msg);

void			MSG_WriteBits (msg_t *msg, int value, int bits);
void			MSG_WriteBool (msg_t *msg, bool value);
void			MSG_WriteChar (msg_t *msg, int value);
void			MSG_WriteByte (msg_t *msg, int value);
void			MSG_WriteShort (msg_t *msg, int value);
void			MSG_WriteWord (msg_t *msg, int value);
void			MSG_WriteLong (msg_t *msg, int value);
void			MSG_WriteHalf (msg_t *msg, float value);
void			MSG_WriteFloat (msg_t *msg, float value);
void			MSG_WriteAngle (msg_t *msg, float angle);
void			MSG_WriteAngle8 (msg_t *msg, float angle);
void			MSG_WriteAngle16 (msg_t *msg, float angle);
void			MSG_WriteAngles (msg_t *msg, const glqAngles &angles);
void			MSG_WriteAngles8 (msg_t *msg, const glqAngles &angles);
void			MSG_WriteAngles16 (msg_t *msg, const glqAngles &angles);
void			MSG_WriteVec2 (msg_t *msg, const glqVec2 &vec);
void			MSG_WriteVec3 (msg_t *msg, const glqVec3 &vec);
void			MSG_WriteVec4 (msg_t *msg, const glqVec4 &vec);
void			MSG_WriteVec5 (msg_t *msg, const glqVec5 &vec);
void			MSG_WriteNormal (msg_t *msg, const glqVec3 &normal);
void			MSG_WriteString (msg_t *msg, const char *string);
void			MSG_WriteData (msg_t *msg, const void *data, int size);

void			MSG_WriteDeltaBits (msg_t *msg, int oldValue, int newValue, int bits);
void			MSG_WriteDeltaChar (msg_t *msg, int oldValue, int newValue);
void			MSG_WriteDeltaByte (msg_t *msg, int oldValue, int newValue);
void			MSG_WriteDeltaShort (msg_t *msg, int oldValue, int newValue);
void			MSG_WriteDeltaWord (msg_t *msg, int oldValue, int newValue);
void			MSG_WriteDeltaLong (msg_t *msg, int oldValue, int newValue);
void			MSG_WriteDeltaHalf (msg_t *msg, float oldValue, float newValue);
void			MSG_WriteDeltaFloat (msg_t *msg, float oldValue, float newValue);
void			MSG_WriteDeltaAngle (msg_t *msg, float oldAngle, float newAngle);
void			MSG_WriteDeltaAngle8 (msg_t *msg, float oldAngle, float newAngle);
void			MSG_WriteDeltaAngle16 (msg_t *msg, float oldAngle, float newAngle);
void			MSG_WriteDeltaAngles (msg_t *msg, const glqAngles &oldAngles, const glqAngles &newAngles);
void			MSG_WriteDeltaAngles8 (msg_t *msg, const glqAngles &oldAngles, const glqAngles &newAngles);
void			MSG_WriteDeltaAngles16 (msg_t *msg, const glqAngles &oldAngles, const glqAngles &newAngles);
void			MSG_WriteDeltaVec2 (msg_t *msg, const glqVec2 &oldVec, const glqVec2 &newVec);
void			MSG_WriteDeltaVec3 (msg_t *msg, const glqVec3 &oldVec, const glqVec3 &newVec);
void			MSG_WriteDeltaVec4 (msg_t *msg, const glqVec4 &oldVec, const glqVec4 &newVec);
void			MSG_WriteDeltaVec5 (msg_t *msg, const glqVec5 &oldVec, const glqVec5 &newVec);
void			MSG_WriteDeltaNormal (msg_t *msg, const glqVec3 &oldNormal, const glqVec3 &newNormal);

// Reading functions
int				MSG_GetReadState (msg_t *msg);
void			MSG_SetReadState (msg_t *msg, int bits);
void			MSG_ClearReadState (msg_t *msg);

int				MSG_RemainingReadBits (msg_t *msg);
int				MSG_RemainingReadBytes (msg_t *msg);

void			MSG_ReadAlign (msg_t *msg);

int				MSG_ReadBits (msg_t *msg, int bits);
bool			MSG_ReadBool (msg_t *msg);
int				MSG_ReadChar (msg_t *msg);
int				MSG_ReadByte (msg_t *msg);
int				MSG_ReadShort (msg_t *msg);
int				MSG_ReadWord (msg_t *msg);
int				MSG_ReadLong (msg_t *msg);
float			MSG_ReadHalf (msg_t *msg);
float			MSG_ReadFloat (msg_t *msg);
float			MSG_ReadAngle (msg_t *msg);
float			MSG_ReadAngle8 (msg_t *msg);
float			MSG_ReadAngle16 (msg_t *msg);
glqAngles		MSG_ReadAngles (msg_t *msg);
glqAngles		MSG_ReadAngles8 (msg_t *msg);
glqAngles		MSG_ReadAngles16 (msg_t *msg);
glqVec2			MSG_ReadVec2 (msg_t *msg);
glqVec3			MSG_ReadVec3 (msg_t *msg);
glqVec4			MSG_ReadVec4 (msg_t *msg);
glqVec5			MSG_ReadVec5 (msg_t *msg);
glqVec3			MSG_ReadNormal (msg_t *msg);
int				MSG_ReadString (msg_t *msg, char *string, int maxLength);
int				MSG_ReadData (msg_t *msg, void *data, int size);

int				MSG_ReadDeltaBits (msg_t *msg, int oldValue, int bits);
int				MSG_ReadDeltaChar (msg_t *msg, int oldValue);
int				MSG_ReadDeltaByte (msg_t *msg, int oldValue);
int				MSG_ReadDeltaShort (msg_t *msg, int oldValue);
int				MSG_ReadDeltaWord (msg_t *msg, int oldValue);
int				MSG_ReadDeltaLong (msg_t *msg, int oldValue);
float			MSG_ReadDeltaHalf (msg_t *msg, float oldValue);
float			MSG_ReadDeltaFloat (msg_t *msg, float oldValue);
float			MSG_ReadDeltaAngle (msg_t *msg, float oldAngle);
float			MSG_ReadDeltaAngle8 (msg_t *msg, float oldAngle);
float			MSG_ReadDeltaAngle16 (msg_t *msg, float oldAngle);
glqAngles		MSG_ReadDeltaAngles (msg_t *msg, const glqAngles &oldAngles);
glqAngles		MSG_ReadDeltaAngles8 (msg_t *msg, const glqAngles &oldAngles);
glqAngles		MSG_ReadDeltaAngles16 (msg_t *msg, const glqAngles &oldAngles);
glqVec2			MSG_ReadDeltaVec2 (msg_t *msg, const glqVec2 &oldVec);
glqVec3			MSG_ReadDeltaVec3 (msg_t *msg, const glqVec3 &oldVec);
glqVec4			MSG_ReadDeltaVec4 (msg_t *msg, const glqVec4 &oldVec);
glqVec5			MSG_ReadDeltaVec5 (msg_t *msg, const glqVec5 &oldVec);
glqVec3			MSG_ReadDeltaNormal (msg_t *msg, const glqVec3 &oldNormal);


#endif	// __MSGSYSTEM_H__